package com.sun.showcase.pojo;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;

public class Pager<T>
  implements Serializable
{
  public static final Long DEFAULT_PAGE_SIZE = Long.valueOf(20L);
  private static final long serialVersionUID = 609222305391683918L;
  private List<T> records;
  private Long totalRecords;
  private Long currentPage;
  private Long pageSize;
  private String orderProperty;
  private String order;
  private boolean countTotal;

  public Pager()
  {
    this.records = new ArrayList<T>();

    this.totalRecords = Long.valueOf(0L);

    this.currentPage = Long.valueOf(1L);

    this.pageSize = DEFAULT_PAGE_SIZE;

    this.orderProperty = "";

    this.order = "";

    this.countTotal = true;
  }
  public List<T> getRecords() {
    return this.records;
  }
  public void setRecords(List<T> records) {
    this.records = records;
  }
  public Long getTotalRecords() {
    return this.totalRecords;
  }
  public void setTotalRecords(Long totalRecords) {
    this.totalRecords = totalRecords;
  }
  public Long getCurrentPage() {
    return this.currentPage;
  }
  public void setCurrentPage(Long currentPage) {
    if (currentPage.longValue() <= 0L)
      this.currentPage = Long.valueOf(1L);
    else
      this.currentPage = currentPage;
  }

  public Long getPageSize() {
    return this.pageSize;
  }
  public void setPageSize(Long pageSize) {
    if (pageSize.longValue() <= 0L)
      this.pageSize = Long.valueOf(1L);
    else
      this.pageSize = pageSize;
  }

  public boolean isCountTotal() {
    return this.countTotal;
  }
  public void setCountTotal(boolean countTotal) {
    this.countTotal = countTotal;
  }

  public Long getTotalPages()
  {
    if (getTotalRecords().longValue() == 0L) {
      return Long.valueOf(1L);
    }
    Long div = Long.valueOf(getTotalRecords().longValue() / getPageSize().longValue());
    Long sub = Long.valueOf(getTotalRecords().longValue() % getPageSize().longValue());
    if (sub.longValue() == 0L) {
      return div;
    }
    return Long.valueOf(div.longValue() + 1L);
  }

  public boolean isOrderBySetted()
  {
    return (StringUtils.isNotBlank(this.order)) && (StringUtils.isNotBlank(this.orderProperty));
  }

  public Long getFirstResult()
  {
    return Long.valueOf((getCurrentPage().longValue() - 1L) * getPageSize().longValue());
  }

  public Long getFirstResultExt()
  {
    Long firstPage = getFirstResult();
    return Long.valueOf(firstPage.longValue() <= 0L ? 0L : firstPage.longValue() - 1L);
  }
  public String getOrderProperty() {
    return this.orderProperty;
  }
  public void setOrderProperty(String orderProperty) {
    this.orderProperty = orderProperty;
  }
  public String getOrder() {
    return this.order;
  }
  public void setOrder(String order) {
    String lowcaseOrderDir = StringUtils.lowerCase(order);

    String[] orderDirs = StringUtils.split(lowcaseOrderDir, ',');
    for (String orderDirStr : orderDirs) {
      if ((!StringUtils.equals("desc", orderDirStr)) && (!StringUtils.equals("asc", orderDirStr))) {
        throw new IllegalArgumentException("排序方向" + orderDirStr + "不是合法值");
      }
    }
    this.order = lowcaseOrderDir;
  }

  public List<Sort> getSort()
  {
    String[] orderBys = StringUtils.split(this.orderProperty, ',');
    String[] orderDirs = StringUtils.split(this.order, ',');
    Validate.isTrue(orderBys.length == orderDirs.length, "分页多重排序参数中,排序字段与排序方向的个数不相等", new Object[0]);

    List<Sort> orders = new ArrayList<Sort>();
    for (int i = 0; i < orderBys.length; i++) {
      orders.add(new Sort(orderBys[i], orderDirs[i]));
    }
    return orders;
  }

  public static <X, M> Pager<M> cloneFromPager(Pager<X> pager)
  {
    Pager<M> result = new Pager<M>();
    result.setCountTotal(pager.isCountTotal());
    result.setCurrentPage(pager.getCurrentPage());
    result.setOrder(pager.getOrder());
    result.setOrderProperty(pager.getOrderProperty());
    result.setPageSize(pager.getPageSize());
    result.setTotalRecords(pager.getTotalRecords());
    return result;
  }

  public static <X> Pager<X> cloneFromPager(Pager<X> pager, long totalRecords, List<X> records)
  {
    Pager<X> result = cloneFromPager(pager);
    result.setTotalRecords(Long.valueOf(totalRecords));
    result.setRecords(records);
    return result;
  }
  public static class Sort {
    public static final String ASC = "asc";
    public static final String DESC = "desc";
    private final String property;
    private final String dir;

    public Sort(String property, String dir) { this.property = property;
      this.dir = dir; }

    public String getProperty()
    {
      return this.property;
    }

    public String getDir() {
      return this.dir;
    }
  }
}